<?php

class Cache {
  var $cache_ttl = 600;
  var $cache_dir = '_cache/';
  var $debug = 1;
  
  //Constructor
  function Cache($cache_dir, $cache_ttl) {
    $this->cache_dir = $cache_dir;
    $this->cache_ttl = $cache_ttl;
    $this->timer = GetMicroTime(); 
  }
  
  //Get content from cache
  function GetCached($page, $method, $query) {
    $filename = $this->ConstructID($page, $method, $query);
    if (!@file_exists($filename))
      return false;
    if ((time()-@filemtime($filename)) > $this->cache_ttl)
      return false;
    return @file_get_contents($filename);
  }
  
  function ConstructID($page, $method, $query) {
    $page = strtolower(str_replace('\\', '', str_replace("'", '', str_replace('_', '', $page))));
    $filename = $this->cache_dir.md5($page).'_'.$method.'_'.$query;
    return $filename;
  }
  
  //Get timestamp of content from cache
  function GetCachedTime($page, $method, $query) {
    $filename = $this->ConstructID($page, $method, $query);
    if (@file_exists($filename) && (time()-@filemtime($filename)) <= $this->cache_ttl) {
      return @filemtime($filename);
    } else {
      return false;
    }
  }
  
  //Store content to cache
  function StoreToCache($data, $page=false, $method=false, $query=false) {
    if (!$page)   $page   = $this->page;
    if (!$method) $method = $this->method;
    if (!$query)  $query  = $this->query;
    $page = strtolower(str_replace('\\', '', str_replace("'", '', str_replace('_', '', $page))));
    $filename = $this->ConstructID($page, $method, $query);
    $fp = @fopen ($filename, 'w');
    fputs ($fp, $data);
    fclose ($fp); 
    @chmod($filename, octdec('0777'));
    return true;
  }
  
  //Invalidate the cache
  function CacheInvalidate($page) {
    $page = strtolower(str_replace('\\', '', str_replace("'", '', str_replace('_', '', $page))));
    $files = substr($this->ConstructID($page,'',''),0,-2).'*';
    foreach(glob($files) as $filename) {
      @unlink($filename);
    }
    return true;
  }
  
  function Log($msg) {
    if ($this->debug>1) {
      $fp = fopen ($this->cache_dir.'log', 'a');
      fputs ($fp, $msg.'\n');
      fclose ($fp); 
    }
  }
  
  //Check http-request. May be, output cached version.
  function CheckHttpRequest($page, $method) {
    if (!$page) return false;
    
    foreach ($_GET as $k => $v) {
      if ($k!='v' && $k!='wakka') $_query[$k]=$v;
    }
    if ($_query) {
      ksort($_query);
      reset($_query);
      foreach($_query as $k => $v) {
        $query.=urlencode($k).'='.urlencode($v).'&';
      }
    }
    
    //check cache
    if ($mtime = $this->GetCachedTime($page, $method, $query)) {
      $gmt = gmdate('D, d M Y H:i:s \G\M\T', $mtime);
      $etag = $_SERVER['HTTP_IF_NONE_MATCH'];
      $lastm = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
      
      if ($p = strpos($lastm,";")) $lastm=substr($lastm,0,$p);
      //may be we need HEAD support ???
      if ($_SERVER['REQUEST_METHOD']=='GET') {
        if (!((!$lastm && !$etag) || ($gmt!=$lastm) || $gmt!=trim($etag, '\"'))) {
          header ('HTTP/1.1 304 Not Modified');
          die();
        }
        
        $cached = $this->GetCached($page, $method, $query);
        header ('Last-Modified: '.$gmt);
        header ('ETag: "'.$gmt.'"');
        echo $cached;

        // how much time script take
        if ($this->debug>=1 && strpos($method,'.xml')===false) {
          $ddd = GetMicroTime();
          echo ("<div style='margin:5px 20px; color:#999999'><small>cache time: ".(number_format(($ddd-$this->timer),7)).' s<br /></small></div>');
        }
        if (strpos($method,'.xml')===false) 
          echo '</body></html>'; 
        die();
      }
    }

    //We have no valid cached page
    $this->page = $page;
    $this->method = $method;
    $this->query = $query;
    return true;
  }
  
  function Output() {
    clearstatcache();
    if (!($mtime = $this->GetCachedTime($this->page, $this->method, $this->query)))
      $mtime = time();
      {
        $gmt = gmdate('D, d M Y H:i:s \G\M\T', $mtime);
        $res = &$this->result;
        header ('Last-Modified: '.$gmt);
        header ('ETag: "'.$gmt.'"');
        header ('Content-Type: text/xml');
        echo ($res);
        die();
      }
  }  
}
?>